import multiprocessing
import struct
from CarApi.TestToolApi import Debug
from queue import Queue as ThreadQueue
from typing import Tuple
from struct import Struct
from multiprocessing import Process, Queue as ProcQueue, Event, Manager
from functools import wraps
from threading import Thread
from typing import Optional
import subprocess as sb
import re
import time
import select
import asyncio
import traceback
import socket
import pyaudio
import av
import random


class WebServer:

    def __init__(self, host, port, log_level="info", logging=True, reload=True):
        if logging:
            self.__glDebugQueue = ThreadQueue(5)
        else:
            self.__glDebugQueue = None
        self.__task = None
        self.__taskStatus = False
        self.__glDebug = Debug(self.__glDebugQueue, True, "WebServer::normal")
        self.__host = host
        self.__port = port
        self.__log_level = log_level
        self.__reload = 'true' if reload else 'false'

    def __start(self):
        self.__task = sb.Popen(
            f"python -u WebServerApi/server.py {self.__host} {self.__port} {self.__reload}",
            shell=True,
            stdin=sb.PIPE,
            stdout=sb.PIPE,
            stderr=sb.STDOUT
        )
        nums = 0
        while nums <= 3:
            result = self.__task.stdout.readline().decode()
            if re.search(r'Uvicorn running on', result) is not None:
                self.__taskStatus = True
                break
            nums += 1

    def openServer(self):
        """
        描述：打开Web服务器进程，运行Web服务器
        参数：无
        返回值：无
        """
        if self.__task is None:
            self.__start()
            if not self.__taskStatus:
                self.__glDebug.pushInfo("Web服务器子进程创建失败!", "Error")
                self.__task.kill()
                try:
                    self.__task.wait(3)
                except TimeoutError:
                    raise RuntimeError("Web服务器子进程杀死出现未知错误!")
                self.__glDebug.pushInfo("Web服务器子进程已结束!", "Warn")
            else:
                self.__glDebug.pushInfo("Web服务器子进程开启成功!")
        else:
            self.__glDebug.pushInfo("Web服务器进程已经开启，请勿重复开启!", "Warn")

    def closeServer(self):
        """
        描述：关闭Web服务器进程，停止Web服务器
        参数：无
        返回值：无
        """
        if self.__task is None:
            self.__glDebug.pushInfo("Web服务器进程并未开启，关闭失败！", "Warn")
        else:
            self.__task.terminate()
            try:
                self.__task.wait(3)
            except TimeoutError:
                raise RuntimeError("Web服务器子进程关闭失败!")
            self.__glDebug.pushInfo("Web服务器子进程关闭成功!")

    def isOpened(self) -> bool:
        """
        描述：查看Web服务器进程是否在运行过程中
        参数：无
        返回值：运行的状态[bool]
        """
        if self.__task.poll() is None:
            return False
        else:
            return True


# class VideoMainSentServer(Process):
#
#     def __init__(
#             self,
#             mainSentVideoPort: int,
#             sent_channel: ProcQueue,
#             ip_address: str = '10.1.0.5',
#             logging=True
#     ):
#         super(VideoMainSentServer, self).__init__()
#         if logging:
#             self.__glDebugQueue = ProcQueue(10)
#         else:
#             self.__glDebugQueue = None
#         self.__mainDebug = Debug(self.__glDebugQueue, True, "SentServer::ProduceThread")
#         # 全局Debug, 数据获取线程Debug, 数据发送线程Debug
#         self.__ipAddress = ip_address
#         self.__mainVideoPort = mainSentVideoPort
#         # IP地址, 主视频流端口
#         self.__ErrorStatus = Event()
#         self.__procQueue = sent_channel
#         # 全局错误状态变量, 如果变为True, 则结束所有线程任务
#
#     async def __taskDataSort(self, recv_channel: ProcQueue,
#                              asyncio_channel: asyncio.Queue):
#         self.__mainDebug.pushInfo("[DataSort] 正在初始化该协程...")
#         mainVideoBuffer = b''
#         structPack = Struct("< Q")
#         mainVideoFrame = 1
#         while not self.__ErrorStatus.is_set():
#             try:
#                 if recv_channel.empty():
#                     await asyncio.sleep(0)
#                 else:
#                     # print("发送了数据")
#                     mainVideo = recv_channel.get()
#                     mainVideoBuffer += mainVideo
#                     if len(mainVideoBuffer) >= 2048:
#                         packNum = int(len(mainVideoBuffer) / 2048)
#                         index = 0
#                         bufferArray = []
#                         for index in range(packNum):
#                             sentBytes = mainVideoBuffer[2048 * index:2048 * (index + 1)]
#                             sentBytes = structPack.pack(mainVideoFrame) + sentBytes
#                             bufferArray.append(sentBytes)
#                             mainVideoFrame += 1
#                         memBytes = mainVideoBuffer[(index + 1) * 2048:]
#                         mainVideoBuffer = memBytes
#                         for each in bufferArray:
#                             await asyncio_channel.put(each)
#             except Exception as e:
#                 self.__mainDebug.pushInfo(
#                     f"[DataSort] \n{traceback.format_exc()}\n----------Error----------",
#                     "Error"
#                 )
#                 self.__mainDebug.pushInfo("[DataSort] 该线程遇到未知错误, 退出!", "Error")
#                 break
#         if self.__ErrorStatus.is_set():
#             self.__mainDebug.pushInfo("[DataSort] 出现全局错误申请, 退出该线程!")
#         self.__ErrorStatus.set()
#
#     async def __taskMainVideoSent(self, port: int, ipAddress: str, channel: asyncio.Queue):
#         self.__mainDebug.pushInfo("[MainVideoSent] 视频流推送协程初始化...")
#         server = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
#         myPoll = select.epoll()
#         myPoll.register(server, select.EPOLLOUT)
#         # 连接次数包，客户端拿来判断自己发送的OK请求是否收到，从而再次发送OK请求
#         self.__mainDebug.pushInfo("[MainVideoSent] 视频流推送协程进入循环...")
#         while not self.__ErrorStatus.is_set():
#             try:
#                 res = myPoll.poll(0)
#                 if len(res) == 0:
#                     await asyncio.sleep(0)
#                 else:
#                     chunk = await channel.get()
#                     server.sendto(chunk, (ipAddress, port))
#             except Exception as e:
#                 self.__mainDebug.pushInfo(
#                     f"[MainVideoSent] \n{traceback.format_exc()}\n----------Error----------",
#                     "Error"
#                 )
#                 self.__mainDebug.pushInfo("[MainVideoSent] 该协程发生错误, 退出!", "Error")
#                 break
#         if self.__ErrorStatus.is_set():
#             self.__mainDebug.pushInfo("[MainVideoSent] 出现全局错误申请, 退出该协程!")
#         self.__ErrorStatus.set()
#
#     def __mainThread(self, channel: ProcQueue, mainVideoPort: int, ipAddress: str):
#         self.__mainDebug.pushInfo("正在初始化发送线程...")
#         myself = self
#         loop = asyncio.new_event_loop()
#         mainVideoQueue = asyncio.Queue(100, loop=loop)
#         dataSortTask = loop.create_task(self.__taskDataSort(channel, mainVideoQueue))
#         mainVideoTask = loop.create_task(self.__taskMainVideoSent(mainVideoPort, ipAddress, mainVideoQueue))
#
#         async def main(__self=myself):
#             await asyncio.gather(
#                 dataSortTask, mainVideoTask
#             )
#
#         self.__mainDebug.pushInfo("发送线程开始运行")
#         loop.run_until_complete(main())
#         self.__ErrorStatus.set()
#         self.__mainDebug.pushInfo("总进程遇到错误, 退出该线程!", "Error")
#
#     def run(self) -> None:
#         tranceChannel = self.__procQueue
#         dataSentThread = Thread(
#             target=self.__mainThread,
#             args=(tranceChannel, self.__mainVideoPort, self.__ipAddress)
#         )
#         dataSentThread.setDaemon(True)
#         dataSentThread.start()
#         dataSentThread.join()
#
#     def openServer(self):
#         self.start()
#
#     def closeServer(self):
#         self.__ErrorStatus.set()
#
#     def isOpened(self):
#         return self.is_alive()


# class VideoSubSentServer(Process):
#
#     def __init__(
#             self,
#             subSentVideoPort: int,
#             sent_channel: ProcQueue,
#             ip_address: str = '10.1.0.5',
#             logging=True
#     ):
#         super(VideoSubSentServer, self).__init__()
#         if logging:
#             self.__glDebugQueue = ProcQueue(10)
#         else:
#             self.__glDebugQueue = None
#         self.__mainDebug = Debug(self.__glDebugQueue, True, "SentServer::ProduceThread")
#         # 全局Debug, 数据获取线程Debug, 数据发送线程Debug
#         self.__ipAddress = ip_address
#         self.__subVideoPort = subSentVideoPort
#         # IP地址, 主视频流端口
#         self.__ErrorStatus = Event()
#         self.__procQueue = sent_channel
#         # 全局错误状态变量, 如果变为True, 则结束所有线程任务
#
#     async def __taskDataSort(self, recv_channel: ProcQueue,
#                              asyncio_channel: asyncio.Queue):
#         self.__mainDebug.pushInfo("[DataSort] 正在初始化该协程...")
#         subVideoBuffer = b''
#         structPack = Struct("< Q")
#         subVideoFrame = 1
#         while not self.__ErrorStatus.is_set():
#             try:
#                 if recv_channel.empty():
#                     await asyncio.sleep(0)
#                 else:
#                     # print("发送了数据")
#                     subVideo = recv_channel.get()
#                     subVideoBuffer += subVideo
#                     if len(subVideoBuffer) >= 2048:
#                         packNum = int(len(subVideoBuffer) / 2048)
#                         index = 0
#                         bufferArray = []
#                         for index in range(packNum):
#                             sentBytes = subVideoBuffer[2048 * index:2048 * (index + 1)]
#                             sentBytes = structPack.pack(subVideoFrame) + sentBytes
#                             bufferArray.append(sentBytes)
#                             subVideoFrame += 1
#                         memBytes = subVideoBuffer[(index + 1) * 2048:]
#                         subVideoBuffer = memBytes
#                         for each in bufferArray:
#                             await asyncio_channel.put(each)
#             except Exception as e:
#                 self.__mainDebug.pushInfo(
#                     f"[DataSort] \n{traceback.format_exc()}\n----------Error----------",
#                     "Error"
#                 )
#                 self.__mainDebug.pushInfo("[DataSort] 该线程遇到未知错误, 退出!", "Error")
#                 break
#         if self.__ErrorStatus.is_set():
#             self.__mainDebug.pushInfo("[DataSort] 出现全局错误申请, 退出该线程!")
#         self.__ErrorStatus.set()
#
#     async def __taskSubVideoSent(self, port: int, ipAddress: str, channel: asyncio.Queue):
#         self.__mainDebug.pushInfo("[SubVideoSent] 视频流推送协程初始化...")
#         server = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
#         myPoll = select.epoll()
#         myPoll.register(server, select.EPOLLOUT)
#         # 连接次数包，客户端拿来判断自己发送的OK请求是否收到，从而再次发送OK请求
#         self.__mainDebug.pushInfo("[SubVideoSent] 视频流推送协程进入循环...")
#         while not self.__ErrorStatus.is_set():
#             try:
#                 res = myPoll.poll(0)
#                 if len(res) == 0:
#                     await asyncio.sleep(0)
#                 else:
#                     chunk = await channel.get()
#                     server.sendto(chunk, (ipAddress, port))
#                     await asyncio.sleep(0)
#             except Exception as e:
#                 self.__mainDebug.pushInfo(
#                     f"[SubVideoSent] \n{traceback.format_exc()}\n----------Error----------",
#                     "Error"
#                 )
#                 self.__mainDebug.pushInfo("[SubVideoSent] 该协程发生错误, 退出!", "Error")
#                 break
#         if self.__ErrorStatus.is_set():
#             self.__mainDebug.pushInfo("[SubVideoSent] 出现全局错误申请, 退出该协程!")
#         self.__ErrorStatus.set()
#
#     def __mainThread(self, channel: ProcQueue, mainVideoPort: int, ipAddress: str):
#         self.__mainDebug.pushInfo("正在初始化发送线程...")
#         myself = self
#         loop = asyncio.new_event_loop()
#         subVideoQueue = asyncio.Queue(20, loop=loop)
#         dataSortTask = loop.create_task(self.__taskDataSort(channel, subVideoQueue))
#         subVideoTask = loop.create_task(self.__taskSubVideoSent(mainVideoPort, ipAddress, subVideoQueue))
#
#         async def main(__self=myself):
#             await asyncio.gather(
#                 dataSortTask, subVideoTask
#             )
#
#         self.__mainDebug.pushInfo("发送线程开始运行")
#         loop.run_until_complete(main())
#         self.__ErrorStatus.set()
#         self.__mainDebug.pushInfo("总进程遇到错误, 退出该线程!", "Error")
#
#     def run(self) -> None:
#         tranceChannel = self.__procQueue
#         dataSentThread = Thread(
#             target=self.__mainThread,
#             args=(tranceChannel, self.__subVideoPort, self.__ipAddress)
#         )
#         dataSentThread.setDaemon(True)
#         dataSentThread.start()
#         dataSentThread.join()
#
#     def openServer(self):
#         self.start()
#
#     def closeServer(self):
#         self.__ErrorStatus.set()
#
#     def isOpened(self):
#         return self.is_alive()

class VideoMainCaptureServer(Process):

    def __init__(
            self,
            mainSentVideoPort: int,
            ip_address: str = '10.1.0.5',
            logging=True
    ):
        super(VideoMainCaptureServer, self).__init__()
        if logging:
            self.__glDebugQueue = ProcQueue(10)
        else:
            self.__glDebugQueue = None
        self.__mainDebug = Debug(self.__glDebugQueue, True, "下位机系统-服务器模块-主视频流采集进程")
        self.__ipAddress = ip_address
        self.__mainVideoPort = mainSentVideoPort
        self.__ErrorStatus = Event()

    def __mainProduceThread(self, channel: ThreadQueue):
        self.__mainDebug.info("正在初始化生产线程...")
        commandCheckPort = "ls -l /dev/ | grep usb_cam"
        checkProc = sb.Popen(commandCheckPort, stdout=sb.PIPE, stderr=sb.STDOUT, shell=True)
        stdin, stderr = checkProc.communicate()
        text = stdin.decode()
        if text != '':
            resPort = re.search(r'video\d', text)
            if resPort is None:
                self.__ErrorStatus.set()
                return
            else:
                usb_cam = resPort.group()
                rasp_cam = 'video2' if usb_cam == 'video0' else 'video0'
        else:
            self.__ErrorStatus.set()
            return
        # 查看usb摄像头分配的设备端口，以此分开初始化两个摄像头
        command_rasp_cam = [
            'ffmpeg', '-f', 'video4linux2', '-i', f'/dev/{rasp_cam}', '-r', '30', '-s', '1280x720', '-b:v', "1500k",
            '-y', '-tune', 'zerolatency', '-sc_threshold', '499',
            '-profile', 'baseline', '-preset', 'ultrafast', '-vcodec', 'h264_omx',
            '-f', 'h264', '-pix_fmt', 'yuv420p', 'udp://127.0.0.1:5454'
        ]
        rasp_proc = sb.Popen(command_rasp_cam, stdout=sb.PIPE, bufsize=2 ** 20)
        # rasp_proc = sb.Popen(command_rasp_cam, stdout=sb.DEVNULL, stderr=sb.DEVNULL)
        self.__mainDebug.info("接收初始化...")
        server = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
        server.bind(('127.0.0.1', 5454))
        myPoll = select.epoll()
        myPoll.register(server, select.EPOLLIN)
        while not self.__ErrorStatus.is_set():
            try:
                res = myPoll.poll(0)
                if len(res) == 0:
                    pass
                else:
                    chunk, _ = server.recvfrom(65525)
                    channel.put(chunk)
            except Exception as e:
                self.__mainDebug.error(
                    f"[图像生产器] \n{traceback.format_exc()}\n----------Error----------"
                )
                self.__mainDebug.error("[图像生产器] 该线程发生错误, 退出!")
                break
        rasp_proc.terminate()
        if self.__ErrorStatus.is_set():
            self.__mainDebug.error("[图像生产器] 出现全局错误申请, 退出该进程!")
        self.__ErrorStatus.set()
        self.__mainDebug.warn("[图像生产器] 总进程遇到错误, 退出该进程!")

    def __MainVideoSentThread(self, port: int, ipAddress: str, channel: ThreadQueue):
        self.__mainDebug.info("[图像发送器] 视频流推送协程初始化...")
        server = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
        myPoll = select.epoll()
        myPoll.register(server, select.EPOLLOUT)
        # 连接次数包，客户端拿来判断自己发送的OK请求是否收到，从而再次发送OK请求
        self.__mainDebug.info("[图像发送器] 视频流推送协程进入循环...")
        while not self.__ErrorStatus.is_set():
            try:
                res = myPoll.poll(0)
                if len(res) == 0:
                    pass
                else:
                    if channel.empty():
                        time.sleep(0)
                    else:
                        lastTime = time.time()
                        chunk = channel.get()
                        nowTime = time.time()
                        server.sendto(chunk, (ipAddress, port))
            except Exception as e:
                self.__mainDebug.error(
                    f"[MainVideoSent] \n{traceback.format_exc()}\n----------Error----------",
                )
                self.__mainDebug.error("[MainVideoSent] 该协程发生错误, 退出!")
                break
        if self.__ErrorStatus.is_set():
            self.__mainDebug.error("[MainVideoSent] 出现全局错误申请, 退出该协程!")
        self.__ErrorStatus.set()
        self.__mainDebug.warn("[MainVideoSent] 总进程遇到错误, 退出该线程!")

    def run(self) -> None:
        tranceChannel = ThreadQueue(100)
        dataGetThread = Thread(
            target=self.__mainProduceThread,
            args=(tranceChannel,)
        )
        dataSentThread = Thread(
            target=self.__MainVideoSentThread,
            args=(self.__mainVideoPort, self.__ipAddress, tranceChannel)
        )
        dataSentThread.setDaemon(True)
        dataGetThread.setDaemon(True)
        dataSentThread.start()
        dataGetThread.start()
        dataSentThread.join()
        dataGetThread.join()

    def openServer(self):
        self.start()

    def closeServer(self):
        self.__ErrorStatus.set()

    def isOpened(self):
        return self.is_alive()


class VideoSubCaptureServer(Process):

    def __init__(
            self,
            subSentVideoPort: int,
            ip_address: str = '10.1.0.5',
            logging=True
    ):
        super(VideoSubCaptureServer, self).__init__()
        if logging:
            self.__glDebugQueue = ProcQueue(10)
        else:
            self.__glDebugQueue = None
        self.__mainDebug = Debug(self.__glDebugQueue, True, "SubCaptureServer::produce")
        self.__ipAddress = ip_address
        self.__subVideoPort = subSentVideoPort
        self.__ErrorStatus = Event()

    def __subProduceThread(self, channel: ThreadQueue):
        self.__mainDebug.pushInfo("[Produce] 正在初始化生产线程...")
        commandCheckPort = "ls -l /dev/ | grep usb_cam"
        checkProc = sb.Popen(commandCheckPort, stdout=sb.PIPE, stderr=sb.STDOUT, shell=True)
        stdin, stderr = checkProc.communicate()
        text = stdin.decode()
        if text != '':
            resPort = re.search(r'video\d', text)
            if resPort is None:
                self.__ErrorStatus.set()
                return
            else:
                usb_cam = resPort.group()
                rasp_cam = 'video2' if usb_cam == 'video0' else 'video0'
                usb_cam = 'video2' if usb_cam == 'video0' else 'video1'
        else:
            self.__ErrorStatus.set()
            return
        # 查看usb摄像头分配的设备端口，以此分开初始化两个摄像头
        command_usb_cam = [
            'ffmpeg', '-f', 'video4linux2', '-i', f'/dev/{usb_cam}', '-r', '30', '-s', '166x166', '-b:v', "1000k",
            '-y', '-tune', 'zerolatency', '-sc_threshold', '499',
            '-profile', 'baseline', '-preset', 'ultrafast', '-vcodec', 'h264_omx',
            '-f', 'h264', '-pix_fmt', 'yuv420p', 'udp://127.0.0.1:5455'
        ]
        # rasp_proc = sb.Popen(command_rasp_cam, stdout=sb.PIPE, bufsize=2**20)
        usb_proc = sb.Popen(command_usb_cam, stdout=sb.DEVNULL, stderr=sb.DEVNULL)
        self.__mainDebug.pushInfo("[Produce] 接收初始化...")
        server = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
        server.bind(('127.0.0.1', 5455))
        myPoll = select.epoll()
        myPoll.register(server, select.EPOLLIN)
        while not self.__ErrorStatus.is_set():
            try:
                res = myPoll.poll(0)
                if len(res) == 0:
                    pass
                else:
                    chunk, _ = server.recvfrom(65525)
                    channel.put(chunk)
            except Exception as e:
                self.__mainDebug.pushInfo(
                    f"[Produce] \n{traceback.format_exc()}\n----------Error----------",
                    "Error"
                )
                self.__mainDebug.pushInfo("[Produce] 该线程发生错误, 退出!", "Error")
                break
        usb_proc.terminate()
        if self.__ErrorStatus.is_set():
            self.__mainDebug.pushInfo("[Produce] 出现全局错误申请, 退出该协程!")
        self.__ErrorStatus.set()
        self.__mainDebug.pushInfo("[Produce] 总进程遇到错误, 退出该线程!", "Error")

    async def __taskSentData(self, channels: asyncio.Queue, channel_thread: ProcQueue):
        self.__mainDebug.pushInfo("[SentData] 传输协程初始化...")
        while not self.__ErrorStatus.is_set():
            try:
                main_video = await channels.get()
                if channel_thread.full():
                    await asyncio.sleep(0)
                else:
                    channel_thread.put(main_video)
                    await asyncio.sleep(0.0001)
            except Exception as e:
                self.__mainDebug.pushInfo(
                    f"[SentData] \n{traceback.format_exc()}\n----------Error----------",
                    "Error"
                )
                self.__mainDebug.pushInfo("[SentData] 该协程发生错误, 退出!", "Error")
                break
        if self.__ErrorStatus.is_set():
            self.__mainDebug.pushInfo("[SentData] 出现全局错误申请, 退出该协程!")
        self.__ErrorStatus.set()

    def __SubVideoSentThread(self, port: int, ipAddress: str, channel: ThreadQueue):
        self.__mainDebug.pushInfo("[SubVideoSent] 视频流推送协程初始化...")
        server = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
        myPoll = select.epoll()
        myPoll.register(server, select.EPOLLOUT)
        # 连接次数包，客户端拿来判断自己发送的OK请求是否收到，从而再次发送OK请求
        self.__mainDebug.pushInfo("[SubVideoSent] 视频流推送协程进入循环...")
        while not self.__ErrorStatus.is_set():
            try:
                res = myPoll.poll(0)
                if len(res) == 0:
                    pass
                else:
                    lastTime = time.time()
                    chunk = channel.get()
                    nowTime = time.time()
                    server.sendto(chunk, (ipAddress, port))
            except Exception as e:
                self.__mainDebug.pushInfo(
                    f"[SubVideoSent] \n{traceback.format_exc()}\n----------Error----------",
                    "Error"
                )
                self.__mainDebug.pushInfo("[SubVideoSent] 该协程发生错误, 退出!", "Error")
                break
        if self.__ErrorStatus.is_set():
            self.__mainDebug.pushInfo("[SubVideoSent] 出现全局错误申请, 退出该协程!")
        self.__ErrorStatus.set()

    def run(self) -> None:
        tranceChannel = ThreadQueue(100)
        dataGetThread = Thread(
            target=self.__subProduceThread,
            args=(tranceChannel,)
        )
        dataSentThread = Thread(
            target=self.__SubVideoSentThread,
            args=(self.__subVideoPort, self.__ipAddress, tranceChannel)
        )
        dataSentThread.setDaemon(True)
        dataGetThread.setDaemon(True)
        dataSentThread.start()
        dataGetThread.start()
        dataSentThread.join()
        dataGetThread.join()

    def openServer(self):
        self.start()

    def closeServer(self):
        self.__ErrorStatus.set()

    def isOpened(self):
        return self.is_alive()


class VideoRecvServer(Process):

    def __init__(
            self,
            recv_port: int,
            logging=True
    ):
        super(VideoRecvServer, self).__init__()
        if logging:
            self.__glDebugQueue = ProcQueue(10)
        else:
            self.__glDebugQueue = None
        self.__recvPort = recv_port
        self.__mainThreadDebug = Debug(self.__glDebugQueue, True, "VideoRecvServer::main")
        self.__procQueue = ProcQueue(1)
        self.__ErrorStatus = Event()

    async def __taskRecv(self, recv_port: int, channels: asyncio.Queue):
        self.__mainThreadDebug.pushInfo("[TaskRecv] 视频流接收协程初始化...")
        server = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
        server.bind(('10.1.0.4', recv_port))
        myPoll = select.epoll()
        myPoll.register(server, select.EPOLLIN)
        self.__mainThreadDebug.pushInfo("[TaskRecv] 已进入接收循环...")
        while not self.__ErrorStatus.is_set():
            try:
                res = myPoll.poll(0)
                if len(res) == 0:
                    await asyncio.sleep(0)
                else:
                    recvBytes, _ = server.recvfrom(65535)
                    await channels.put(recvBytes)
            except Exception as e:
                self.__mainThreadDebug.pushInfo(
                    f"[TaskRecv] \n{traceback.format_exc()}\n----------Error----------",
                    "Error"
                )
                self.__mainThreadDebug.pushInfo("[TaskRecv] 该协程发生错误, 退出!", "Error")
                break
        if self.__ErrorStatus.is_set():
            self.__mainThreadDebug.pushInfo("[TaskRecv] 出现全局错误申请, 退出该协程!")
        self.__ErrorStatus.set()

    async def __taskUpdate(self, channels: asyncio.Queue, main_channels: ProcQueue):
        self.__mainThreadDebug.pushInfo("[TaskUpdate] 视频流更新协程初始化...")
        codec = av.CodecContext.create('h264', 'r')
        self.__mainThreadDebug.pushInfo("[TaskUpdate] 已进入更新循环...")
        while not self.__ErrorStatus.is_set():
            try:
                chunk = await channels.get()
                # meta_chunk = struct.Struct('< Q').unpack(chunk[:8])[0]
                raw_chunk = chunk[8:]
                packets = codec.parse(raw_chunk)
                for packet in packets:
                    frames = codec.decode(packet)
                    for frame in frames:
                        frame = frame.reformat(format="bgr24")
                        frame = frame.to_ndarray()
                        main_channels.put(frame)
                        await asyncio.sleep(0)
                await asyncio.sleep(0)
            except Exception as e:
                self.__mainThreadDebug.pushInfo(
                    f"[TaskUpdate] \n{traceback.format_exc()}\n----------Error----------",
                    "Error"
                )
                self.__mainThreadDebug.pushInfo("[TaskUpdate] 该协程发生错误, 退出!", "Error")
                break
        if self.__ErrorStatus.is_set():
            self.__mainThreadDebug.pushInfo("[TaskUpdate] 出现全局错误申请, 退出该协程!")
        self.__ErrorStatus.set()

    def __mainThread(self, recv_port, proc_queue):
        self.__mainThreadDebug.pushInfo("正在初始化总线程")
        myself = self
        loop = asyncio.new_event_loop()
        channel = asyncio.Queue(20, loop=loop)
        taskRecv = loop.create_task(self.__taskRecv(recv_port, channel))
        taskUpdate = loop.create_task(self.__taskUpdate(channel, proc_queue))

        async def main(__self=myself):
            await asyncio.gather(
                taskRecv, taskUpdate
            )

        self.__mainThreadDebug.pushInfo("发送线程开始运行")
        loop.run_until_complete(main())
        self.__ErrorStatus.set()
        self.__mainThreadDebug.pushInfo("总进程遇到错误, 退出该线程!", "Error")

    def run(self) -> None:
        recv_port = self.__recvPort
        proc_queue = self.__procQueue
        mainThread = Thread(
            target=self.__mainThread,
            args=(recv_port, proc_queue)
        )
        mainThread.setDaemon(True)
        mainThread.start()
        mainThread.join()

    def openServer(self):
        self.start()

    def closeServer(self):
        self.__ErrorStatus.set()

    def isOpened(self):
        return self.is_alive()

    def read(self):
        if self.__procQueue.empty():
            return False
        else:
            res = self.__procQueue.get()
            return res


class AudioRecvServer(Process):

    def __init__(
            self,
            recv_port: int,
            logging=True
    ):
        super(AudioRecvServer, self).__init__()
        if logging:
            self.__glDebugQueue = ProcQueue(10)
        else:
            self.__glDebugQueue = None
        self.__mainProduceDebug = Debug(self.__glDebugQueue, True, "AudioRecvServer::produce")
        self.__mainTranceDebug = Debug(self.__glDebugQueue, True, "AudioRecvServer::trance")
        self.__mainDebug = Debug(self.__glDebugQueue, True, "AudioServer::normal")
        self.__ErrorStatus = Event()
        self.__recvPort = recv_port

    def __taskRecv(self, recv_channel: ThreadQueue, recv_port: int):
        self.__mainTranceDebug.pushInfo("[TaskRecv] 音频接收线程初始化...")
        server = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
        self.__mainTranceDebug.pushInfo("[TaskRecv] 已初始化Socket")
        server.bind(('10.1.0.4', recv_port))
        myPoll = select.epoll()
        myPoll.register(server, select.EPOLLIN)
        self.__mainTranceDebug.pushInfo("[TaskRecv] 已进入接收循环...")
        while not self.__ErrorStatus.is_set():
            try:
                res = myPoll.poll(0)
                if len(res) == 0:
                    time.sleep(0)
                else:
                    raw_data, _ = server.recvfrom(65535)
                    recv_channel.put(raw_data)
            except Exception as e:
                self.__mainTranceDebug.pushInfo(
                    f"[TaskRecv] \n{traceback.format_exc()}\n----------Error----------",
                    "Error"
                )
                self.__mainTranceDebug.pushInfo("[TaskRecv] 该线程发生错误, 退出!", "Error")
                break
        if self.__ErrorStatus.is_set():
            self.__mainTranceDebug.pushInfo("[TaskRecv] 出现全局错误申请, 退出该线程!")
        self.__ErrorStatus.set()

    def __taskOutput(self, stream, recv_channel: ThreadQueue):
        self.__mainTranceDebug.pushInfo("[TaskOut] 音频发送线程初始化...")
        self.__mainTranceDebug.pushInfo("[TaskOut] 已进入发送循环...")
        while not self.__ErrorStatus.is_set():
            try:
                writeable_nums = stream.get_write_available()
                if writeable_nums == 0:
                    time.sleep(0)
                else:
                    lastTime = time.time()
                    raw_data = recv_channel.get()
                    nowTime = time.time()
                    stream.write(raw_data)
            except Exception as e:
                self.__mainTranceDebug.pushInfo(
                    f"[TaskOut] \n{traceback.format_exc()}\n----------Error----------",
                    "Error"
                )
                self.__mainTranceDebug.pushInfo("[TaskOut] 该线程发生错误, 退出!", "Error")
                break
        if self.__ErrorStatus.is_set():
            self.__mainTranceDebug.pushInfo("[TaskOut] 出现全局错误申请, 退出该线程!")
        self.__ErrorStatus.set()

    def run(self):
        CHANNELS = 1
        RATE = 44100
        stream = pyaudio.PyAudio().open(
            format=pyaudio.paInt16,
            channels=CHANNELS,
            rate=RATE,
            output=True,
            output_device_index=2
        )
        recv_channel = ThreadQueue(20)
        threadRecv = Thread(
            target=self.__taskRecv,
            args=(recv_channel, self.__recvPort)
        )
        threadOutput = Thread(
            target=self.__taskOutput,
            args=(stream, recv_channel)
        )
        self.__mainDebug.pushInfo("进程开始!", "Warning")
        threadRecv.setDaemon(True)
        threadOutput.setDaemon(True)
        self.__mainDebug.pushInfo("线程守护开启!", "Warning")
        threadRecv.start()
        threadOutput.start()
        threadOutput.join()
        threadRecv.join()
        self.__mainDebug.pushInfo("进程结束!", "Error")

    def openServer(self):
        self.start()

    def closeServer(self):
        self.__ErrorStatus.set()

    def isOpened(self):
        return self.is_alive()


class AudioSentServer(Process):

    def __init__(
            self,
            sent_port: int,
            sent_address: str = '10.1.0.5',
            logging=True
    ):
        super(AudioSentServer, self).__init__()
        if logging:
            self.__glDebugQueue = ProcQueue(10)
        else:
            self.__glDebugQueue = None
        self.__mainProduceDebug = Debug(self.__glDebugQueue, True, "AudioSentServer::produce")
        self.__mainTranceDebug = Debug(self.__glDebugQueue, True, "AudioSentServer::trance")
        self.__mainDebug = Debug(self.__glDebugQueue, True, "AudioSentServer::normal")
        self.__ErrorStatus = Event()
        self.__sentPort = sent_port
        self.__sentAddress = sent_address

    def __taskCapture(self, stream, sent_channel: ThreadQueue):
        self.__mainProduceDebug.pushInfo("[TaskCapture] 音频采集协程初始化...")
        self.__mainProduceDebug.pushInfo("[TaskCapture] 已进入采集循环...")
        while not self.__ErrorStatus.is_set():
            try:
                readable_nums = stream.get_read_available()
                if readable_nums == 0:
                    time.sleep(0)
                else:
                    raw_data = stream.read(readable_nums)
                    sent_channel.put(raw_data)
            except Exception as e:
                self.__mainProduceDebug.pushInfo(
                    f"[TaskCapture] \n{traceback.format_exc()}\n----------Error----------",
                    "Error"
                )
                self.__mainProduceDebug.pushInfo("[TaskCapture] 该线程发生错误, 退出!", "Error")
                break
        if self.__ErrorStatus.is_set():
            self.__mainProduceDebug.pushInfo("[TaskCapture] 出现全局错误申请, 退出该协程!")
        self.__ErrorStatus.set()

    def __taskSent(self, sent_channel: ThreadQueue, sent_port: int, sent_address: str):
        self.__mainProduceDebug.pushInfo("[TaskSent] 音频发送协程初始化...")
        server = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
        myPoll = select.epoll()
        myPoll.register(server, select.EPOLLOUT)
        self.__mainProduceDebug.pushInfo("[TaskSent] 已进入发送循环...")
        while not self.__ErrorStatus.is_set():
            try:
                res = myPoll.poll(0)
                if len(res) == 0:
                    asyncio.sleep(0)
                else:
                    raw_data = sent_channel.get()
                    server.sendto(raw_data, (sent_address, sent_port))
            except Exception as e:
                self.__mainProduceDebug.pushInfo(
                    f"[TaskSent] \n{traceback.format_exc()}\n----------Error----------",
                    "Error"
                )
                self.__mainProduceDebug.pushInfo("[TaskSent] 该协程发生错误, 退出!", "Error")
                break
        if self.__ErrorStatus.is_set():
            self.__mainProduceDebug.pushInfo("[TaskSent] 出现全局错误申请, 退出该协程!")
        self.__ErrorStatus.set()

    def run(self):
        CHANNELS = 1
        RATE = 44100
        stream = pyaudio.PyAudio().open(
            format=pyaudio.paInt16,
            channels=CHANNELS,
            rate=RATE,
            input=True,
            input_device_index=2
        )
        sent_channel = ThreadQueue(20)
        threadCapture = Thread(
            target=self.__taskCapture,
            args=(stream, sent_channel)
        )
        threadSent = Thread(
            target=self.__taskSent,
            args=(sent_channel, self.__sentPort, self.__sentAddress)
        )
        self.__mainDebug.pushInfo("进程开始!", "Warning")
        threadCapture.setDaemon(True)
        threadSent.setDaemon(True)
        threadSent.start()
        threadCapture.start()
        threadSent.join()
        threadCapture.join()

    def openServer(self):
        self.start()

    def closeServer(self):
        self.__ErrorStatus.set()

    def isOpened(self):
        return self.is_alive()


TypeAddress = Tuple[str, int]
TypeThread = Optional[Thread]
TypeThreadQueue = Optional[ProcQueue]
TypeCommandData = Optional[Tuple[bool, bool, bool, bool, int]]


class SocketServer(Process):

    def __init__(
            self,
            qtSAddress: TypeAddress,
            qtRAddress: TypeAddress,
            webSAddress: TypeAddress,
            webRAddress: TypeAddress,
            logging=True
    ):
        super(SocketServer, self).__init__()
        if logging:
            self.__glDebugQueue = ProcQueue(10)
        else:
            self.__glDebugQueue = None
        self.__glDebug = Debug(self.__glDebugQueue, True, "套接字服务器")
        self.__controlDebug = Debug(self.__glDebugQueue, True, "套接字服务器(控制)")
        self.__tranceDebug = Debug(self.__glDebugQueue, True, "套接字服务器(传输)")
        # 全局Debug、控制线程Debug以及传输线程Debug.
        self.__addressQtS = qtSAddress
        self.__addressQtR = qtRAddress
        self.__addressWebS = webSAddress
        self.__addressWebR = webRAddress
        # WebServer和QtClient的地址
        self.__responseData = Manager().dict()
        self.__controlThreadQueue: TypeThreadQueue = ProcQueue(5)
        # 分别为WebServer、QtServer的TCP命令通道以及ControlThread的线程队列(实际上只能是进程)
        self.__ErrorStatus = Event()
        self.__mainEvent = Event()
        self.__subEvent = Event()
        self.__audioSentEvent = Event()
        self.__audioRecvEvent = Event()
        # 全局错误状态变量, 主视频流控制变量, 子视频流控制变量, 音频流发送控制变量, 音频流接收控制变量

    async def __controlDataTask(self):
        self.__controlDebug.pushInfo("[数据更新器] 已进入该协程")
        while not self.__ErrorStatus.is_set():
            try:
                """
                --- 使用树莓派的数据获取API获得数据代码段 ---
                """
                self.__responseData['bat'] = random.randint(1, 100)
                self.__responseData['speed'] = random.randint(0, 9000)
                self.__responseData['signal'] = random.randint(0, 5)
                self.__responseData['lit'] = 10673
                self.__responseData['dim'] = 2659
                self.__responseData['angle'] = 6424
                self.__responseData['time'] = time.time()
                await asyncio.sleep(0)
            except Exception as e:
                self.__controlDebug.pushInfo(
                    f"[数据控制器] \n{traceback.format_exc()}\n----------Error----------",
                    "Error"
                )
                self.__controlDebug.pushInfo("[数据更新器] 该协程遇到未知错误, 退出!", "Error")
                break
        if self.__ErrorStatus.is_set():
            self.__controlDebug.pushInfo("[数据更新器] 遇到全局错误申请, 退出该协程!")
        self.__ErrorStatus.set()

    async def __controlComTask(self):
        self.__controlDebug.pushInfo("[任务执行器] 已进入该协程")
        while not self.__ErrorStatus.is_set():
            try:
                if not self.__controlThreadQueue.empty():
                    command_raw_data: TypeCommandData = self.__controlThreadQueue.get()
                    command_data = struct.Struct('< ? ? ? ? B ? ? ? ? ?').unpack(command_raw_data)
                    if not command_data[9]:
                        self.__controlDebug.pushInfo("[任务执行器] 客户端关闭了")
                        self.__mainEvent.clear()
                        self.__subEvent.clear()
                        self.__audioSentEvent.clear()
                        self.__audioRecvEvent.clear()
                    else:
                        if command_data[0] and not command_data[1]:
                            """
                            --- API前进操作 ---
                            """
                            self.__controlDebug.pushInfo("[任务执行器] 进行下位机前进操作")
                        if command_data[1] and not command_data[0]:
                            """
                            --- API后退操作 ---
                            """
                            self.__controlDebug.pushInfo("[任务执行器] 进行下位机后退操作")
                        if command_data[2] and not command_data[3]:
                            """
                            --- API左转操作 ---
                            """
                            self.__controlDebug.pushInfo("[任务执行器] 进行下位机左转操作")
                        if command_data[3] and not command_data[2]:
                            """
                            --- API右转操作 ---
                            """
                            self.__controlDebug.pushInfo("[任务执行器] 进行下位机右转操作")
                        if command_data[4]:
                            """
                            --- API设置速度 ---
                            """
                            self.__controlDebug.pushInfo("[任务执行器] 设置下位机速度")
                        if command_data[0] == command_data[1] == command_data[2] == command_data[3]:
                            """
                            --- API停止移动 ---
                            """
                            self.__controlDebug.pushInfo("[任务执行器] 进行下位机停止操作")
                        if command_data[5]:
                            self.__controlDebug.pushInfo("[任务执行器] 客户端请求打开主视频流")
                            self.__mainEvent.set()
                        else:
                            self.__mainEvent.clear()
                        if command_data[6]:
                            self.__controlDebug.pushInfo("[任务执行器] 客户端请求打开副视频流")
                            self.__subEvent.set()
                        else:
                            self.__subEvent.clear()
                        if command_data[7]:
                            self.__controlDebug.pushInfo("[任务执行器] 客户端请求服务器发送音频流")
                            self.__audioSentEvent.set()
                        else:
                            self.__audioSentEvent.clear()
                        if command_data[8]:
                            self.__controlDebug.pushInfo("[任务执行器] 客户端请求服务器接收音频流")
                            self.__audioRecvEvent.set()
                        else:
                            self.__audioRecvEvent.clear()
                    await asyncio.sleep(0)
                else:
                    await asyncio.sleep(0)
            except Exception as e:
                self.__controlDebug.pushInfo(
                    f"[任务执行器] \n{traceback.format_exc()}\n----------Error----------",
                    "Error"
                )
                self.__controlDebug.pushInfo("[任务执行器] 该协程遇到未知错误, 退出!", "Error")
                break
        if self.__ErrorStatus.is_set():
            self.__controlDebug.pushInfo("[任务执行器] 遇到全局错误申请, 退出该协程!")
        self.__ErrorStatus.set()

    async def __webCUdpTask(self, myAddress: TypeAddress):
        self.__tranceDebug.pushInfo("[WebCUdpTask] 已进入该协程, 正在进行初始化...")
        udpSocket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
        udpSocket.bind(myAddress)
        inputs, outputs = [udpSocket], []
        nums = 0
        self.__tranceDebug.pushInfo("[WebCUdpTask] 监听Web服务器客户端连接请求中...")
        while True:
            if nums >= 5:
                self.__tranceDebug.pushInfo("[WebCUdpTask] Web服务器验证失败过多, 关闭该协程!")
                self.__ErrorStatus.set()
                break
            if self.__ErrorStatus.is_set():
                break
            readable, writable, exceptional = select.select(inputs, outputs, inputs, 0)
            if len(readable) == 0:
                await asyncio.sleep(0)
            else:
                self.__tranceDebug.pushInfo("[WebCUdpTask] Web服务器连接成功，验证身份中...")
                raw_data, clientAddress = udpSocket.recvfrom(1024)
                if raw_data.decode() == "Hello":
                    self.__tranceDebug.pushInfo("[WebCUdpTask] Web服务器客户端是身份验证成功!")
                    udpSocket.sendto(b'World', clientAddress)
                    break
                else:
                    self.__tranceDebug.pushInfo("[WebCUdpTask] Web服务器客户端身份验证失败!")
                    nums += 1
        while not self.__ErrorStatus.is_set():
            try:
                inputs, outputs = [udpSocket], []
                readable, writable, exceptional = select.select(inputs, outputs, inputs, 0)
                if len(readable) == 0:
                    await asyncio.sleep(0)
                else:
                    clientSock: socket.socket = readable[0]
                    raw_data, _ = clientSock.recvfrom(1024)
                    self.__controlThreadQueue.put(raw_data)
                    """
                    --- 获取  Web端UDP套接字里的数据，并且放入生产队列中 ---
                    """
            except Exception as e:
                self.__tranceDebug.pushInfo(
                    f"[WebCUdpTask] \n{traceback.format_exc()}\n----------Error----------",
                    "Error"
                )
                self.__tranceDebug.pushInfo("[WebCUdpTask] 该协程遇到未知错误, 退出!", "Error")
                break
        if self.__ErrorStatus.is_set():
            self.__tranceDebug.pushInfo("[WebCUdpTask] 遇到全局错误申请, 退出该协程!")
        self.__ErrorStatus.set()

    async def __webDUdpTask(self, myAddress: TypeAddress):
        self.__tranceDebug.pushInfo("[WebDUdpTask] 已进入该协程, 正在进行初始化")
        udpSocket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
        udpSocket.bind(myAddress)
        inputs, outputs = [udpSocket], []
        nums = 0
        clientAddress = None
        self.__tranceDebug.pushInfo("[WebDUdpTask] 监听Web服务器客户端连接请求中...")
        while True:
            if nums >= 5:
                self.__tranceDebug.pushInfo("[WebDUdpTask] Web服务器验证失败过多, 关闭该协程!")
                self.__ErrorStatus.set()
                break
            if self.__ErrorStatus.is_set():
                break
            readable, writable, exceptional = select.select(inputs, outputs, inputs, 0)
            if len(readable) == 0:
                await asyncio.sleep(0)
            else:
                self.__tranceDebug.pushInfo("[WebDUdpTask] Web服务器连接成功, 验证身份中...")
                raw_data, clientAddress = udpSocket.recvfrom(1024)
                if raw_data.decode() == 'Hello':
                    self.__tranceDebug.pushInfo("[WebDUdpTask] Web服务器客户端身份验证成功!")
                    udpSocket.sendto(b'World', clientAddress)
                    break
                else:
                    self.__tranceDebug.pushInfo("[WebDUdpTask] Web服务器客户端身份验证失败!")
                    nums += 1
        while not self.__ErrorStatus.is_set():
            try:
                if len(self.__responseData) == 7:
                    responseData = [
                        self.__responseData['bat'],
                        self.__responseData['speed'],
                        self.__responseData['signal'],
                        self.__responseData['lit'],
                        self.__responseData['dim'],
                        self.__responseData['angle'],
                        self.__responseData['time']
                    ]
                    bytes_data = Struct("< B H B H H h d").pack(*responseData)
                    udpSocket.sendto(bytes_data, clientAddress)
                    await asyncio.sleep(0.1)
                else:
                    await asyncio.sleep(0)
                    """
                    --- 发往Web端的UDP套接字里 ---
                    """
            except Exception as e:
                self.__tranceDebug.pushInfo(
                    f"[WebDUdpTask] \n{traceback.format_exc()}\n----------Error----------",
                    "Error"
                )
                self.__tranceDebug.pushInfo("[WebDUdpTask] 该协程遇到未知错误, 退出!", "Error")
                break
        if self.__ErrorStatus.is_set():
            self.__tranceDebug.pushInfo("[WebDUdpTask] 遇到全局错误申请, 退出该协程!")
        self.__ErrorStatus.set()

    async def __qtCUdpTask(self, myAddress: TypeAddress):
        self.__tranceDebug.pushInfo("[客户端命令接收器] 已进入该协程, 正在进行初始化...")
        udpSocket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
        udpSocket.bind(myAddress)
        inputs, outputs = [udpSocket], []
        self.__tranceDebug.pushInfo("[客户端命令接收器] 监听QT客户端连接请求中...")
        while not self.__ErrorStatus.is_set():
            try:
                readable, writable, exceptional = select.select(inputs, outputs, inputs, 0)
                if len(readable) == 0:
                    await asyncio.sleep(0)
                else:
                    clientSock: socket.socket = readable[0]
                    raw_data, _ = clientSock.recvfrom(1024)
                    self.__controlThreadQueue.put(raw_data)
                    """
                    --- 获取  Qt端UDP套接字里的数据，并且放入生产队列中 ---
                    """
            except Exception as e:
                self.__tranceDebug.pushInfo(
                    f"[客户端命令接收器] \n{traceback.format_exc()}\n----------Error----------",
                    "Error"
                )
                self.__tranceDebug.pushInfo("[客户端命令接收器] 该协程遇到未知错误, 退出!", "Error")
                break
        if self.__ErrorStatus.is_set():
            self.__tranceDebug.pushInfo("[客户端命令接收器] 遇到全局错误申请, 退出该协程!")
        self.__ErrorStatus.set()

    async def __qtDUdpTask(self, myAddress: TypeAddress):
        self.__tranceDebug.pushInfo("[服务端数据发送器] 已进入该协程, 正在进行初始化")
        udpSocket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
        inputs, outputs = [udpSocket], [udpSocket]
        self.__tranceDebug.pushInfo("[服务端数据发送器] 监听Qt客户端连接请求中...")
        while not self.__ErrorStatus.is_set():
            try:
                readable, writable, exceptional = select.select(inputs, outputs, inputs, 0)
                if len(writable) == 0:
                    await asyncio.sleep(0)
                else:
                    if len(self.__responseData) == 7:
                        responseData = [
                            self.__responseData['bat'],
                            self.__responseData['speed'],
                            self.__responseData['signal'],
                            self.__responseData['lit'],
                            self.__responseData['dim'],
                            self.__responseData['angle'],
                            self.__responseData['time']
                        ]
                        bytes_data = Struct("< B H B H H h d").pack(*responseData)
                        udpSocket.sendto(bytes_data, myAddress)
                        await asyncio.sleep(1)
                    else:
                        await asyncio.sleep(0)
                    """
                    --- 发往Qt端的UDP套接字里 ---
                    """
            except Exception as e:
                self.__tranceDebug.pushInfo(
                    f"[服务端数据发送器] \n{traceback.format_exc()}\n----------Error----------",
                    "Error"
                )
                self.__tranceDebug.pushInfo("[服务端数据发送器] 该协程遇到未知错误, 退出!", "Error")
                break
        if self.__ErrorStatus.is_set():
            self.__tranceDebug.pushInfo("[服务端数据发送器] 遇到全局错误申请, 退出该协程!")
        self.__ErrorStatus.set()

    def __mainThread(self, qtSAddress, qtRAddress, webSAddress, webRAddress):
        myself = self

        loop = asyncio.new_event_loop()

        async def main(__self=myself):
            task = [
                __self.__qtDUdpTask(qtSAddress),
                __self.__qtCUdpTask(qtRAddress),
                __self.__controlDataTask(),
                __self.__controlComTask()
            ]
            await asyncio.gather(*task, loop=loop)

        self.__glDebug.pushInfo("总线程开始运行!")
        loop.run_until_complete(main())
        self.__ErrorStatus.set()
        self.__glDebug.pushInfo("总进程遇到错误, 退出该线程!", "Error")

    def run(self) -> None:
        mainThreadObj = Thread(
            target=self.__mainThread,
            args=(
                self.__addressQtS,
                self.__addressQtR,
                self.__addressWebS,
                self.__addressWebR
            )
        )
        mainThreadObj.setDaemon(True)
        mainThreadObj.start()
        mainThreadObj.join()
        self.__ErrorStatus.set()

    def openServer(self):
        self.start()

    def closeServer(self):
        self.__ErrorStatus.set()

    def isOpened(self):
        return self.is_alive()

    def getEvent(self):
        eventDict = {'main': True if self.__mainEvent.is_set() else False,
                     'sub': True if self.__subEvent.is_set() else False,
                     'audioSent': True if self.__audioSentEvent.is_set() else False,
                     'audioRecv': True if self.__audioRecvEvent.is_set() else False}
        return eventDict


if __name__ == '__main__':
    mainCapVideoServer = VideoMainCaptureServer(6100)
    # subCapVideoServer = VideoSubCaptureServer(6101)
    mainCapVideoServer.openServer()
    # subCapVideoServer.openServer()
    while True:
        ret1 = mainCapVideoServer.isOpened()
        # ret2 = subCapVideoServer.isOpened()
        if ret1:
            continue
        else:
            break

    mainCapVideoServer.closeServer()
    # subCapVideoServer.closeServer()

    # while True:
    #     socketServer = SocketServer(
    #         qtSAddress=('10.1.0.5', 6711),
    #         qtRAddress=('10.1.0.4', 6712),
    #         webSAddress=('0.0.0.0', 8102),
    #         webRAddress=('0.0.0.0', 8103),
    #         logging=True
    #     )
    #     print("服务器启动成功")
    #     socketServer.openServer()
    #     print("监听服务器中")
    #     socketServer.join()
    #     socketServer.closeServer()
    #     print("服务器重新启动！")

    # audioRecvServer = AudioRecvServer(6512)
    # audioSentServer = AudioSentServer(6511)
    # audioRecvServer.openServer()
    # audioSentServer.openServer()
    # while audioRecvServer.isOpened() and audioSentServer.isOpened():
    #     try:
    #         pass
    #     except KeyboardInterrupt:
    #         break
    # audioRecvServer.closeServer()
    # audioSentServer.closeServer()
    # audioSentServer.join()
    # audioRecvServer.join()
